package com.xiaoshuidi.cloud.module.rooms.mq.listener;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.xiaoshuidi.cloud.framework.filings.core.FilingsApi;
import com.xiaoshuidi.cloud.framework.filings.core.enums.UriEnum;
import com.xiaoshuidi.cloud.framework.filings.core.service.dto.*;
import com.xiaoshuidi.cloud.module.rooms.controller.admin.roomel.vo.RoomelUpdateReqVO;
import com.xiaoshuidi.cloud.module.rooms.enums.RoomHouseFilingsStatus;
import com.xiaoshuidi.cloud.module.rooms.mq.event.InventoryCheckEvent;
import com.xiaoshuidi.cloud.module.rooms.mq.producer.RoomEsProducer;
import com.xiaoshuidi.cloud.module.rooms.pojo.RoomHouse;
import com.xiaoshuidi.cloud.module.rooms.pojo.RoomHouseFilings;
import com.xiaoshuidi.cloud.module.rooms.pojo.RoomHouseFilingsLogs;
import com.xiaoshuidi.cloud.module.rooms.repository.RoomHouseFilingsLogsRepository;
import com.xiaoshuidi.cloud.module.rooms.repository.RoomHouseFilingsRepository;
import com.xiaoshuidi.cloud.module.rooms.repository.RoomHouseRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 房源信息核验信息同步事件监听
 *
 * @author hans.zhang
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class InventoryCheckListener {

    private final FilingsApi<InventoryCheckResp, InventoryCheckBo> inventoryCheckApi;
    private final FilingsApi<InventoryRoomCheckResp, InventoryRoomCheckBo> inventoryRoomCheckApi;
    private final RoomHouseFilingsRepository roomHouseFilingsRepository;
    private final RoomHouseFilingsLogsRepository roomHouseFilingsLogsRepository;
    private final RoomHouseRepository roomHouseRepository;
    private final RoomEsProducer roomEsProducer;


    /**
     * 异步执行,推送并记录备案数据
     *
     * @param inventoryCheckEvent
     */
    @Async
    @EventListener
    @Transactional(rollbackFor = Exception.class)
    public void filingsListener(InventoryCheckEvent inventoryCheckEvent) {
        log.info("备案事件线程：{}", Thread.currentThread().getName());
        InventoryCheckBo inventoryCheckBo = inventoryCheckEvent.getInventoryCheckBo();
        log.info("备案事件执行,备案数据:{}", JSONObject.toJSONString(inventoryCheckBo));
        CommonFilingsResponse<InventoryCheckResp> response = new CommonFilingsResponse<>();
        try {
            response = inventoryCheckApi.execute(inventoryCheckBo, UriEnum.INVENTORY_CHECK_URI, InventoryCheckResp.class);
        } catch (Exception e) {
            response.setStatus(false);
            response.setMsg(e.getMessage());
            log.error("InventoryCheckListener->filingsListener异常",e);
        }
        log.info("备案数据cardNo:{}响应:{}", inventoryCheckBo.getCardNo(), JSONObject.toJSONString(response));
        // 保存备案响应数据
        RoomHouseFilings roomHouseFilings = new RoomHouseFilings();
        roomHouseFilings.setRoomHouseId(Long.valueOf(inventoryCheckBo.getUniqueDataId()));
        // 备案成功
        if (response.getStatus()) {
            InventoryCheckResp resp = response.getData();
            roomHouseFilings.setExternalHouseId(resp.getHouseId());
            roomHouseFilings.setStatus(RoomHouseFilingsStatus.SUCCESS.getCode());
            roomHouseFilings.setCheckCode(resp.getCheckCode());
            roomHouseFilings.setCheckCodeInDate(resp.getCheckCodeIndate());
            // 推送核验码到es
            // 更新ES数据
            List<RoomelUpdateReqVO> roomelUpdateReqVOS = new ArrayList<>();
            RoomelUpdateReqVO roomelUpdateReqVO = new RoomelUpdateReqVO();
            roomelUpdateReqVO.setId(roomHouseFilings.getRoomHouseId());
            roomelUpdateReqVO.setCheckCode(resp.getCheckCode());
            roomelUpdateReqVO.setCheckCodeInDate(resp.getCheckCodeIndate());
            roomelUpdateReqVOS.add(roomelUpdateReqVO);
            // 更新房源信息到es
            roomEsProducer.updateBatchRoomEl(roomelUpdateReqVOS);
            // 请求合租核验码
            if (ObjectUtil.isNotEmpty(inventoryCheckEvent.getInventoryRoomCheckBo().getLeaseSubHouseSets())) {
                this.roomCheck(inventoryCheckEvent, inventoryCheckBo, resp);
            }
        } else {
            // 备案失败
            roomHouseFilings.setStatus(RoomHouseFilingsStatus.ERROR.getCode());
        }
        roomHouseFilings.setTenantId(inventoryCheckEvent.getTennerId());
        // 如果之前有备案过,则更新原纪录
        RoomHouseFilings filings = roomHouseFilingsRepository.getByRoomHouseId(Long.valueOf(inventoryCheckBo.getUniqueDataId()));
        if (ObjectUtil.isNotEmpty(filings)) {
            filings.setExternalHouseId(roomHouseFilings.getExternalHouseId());
            filings.setStatus(roomHouseFilings.getStatus());
            filings.setCheckCode(roomHouseFilings.getCheckCode());
            filings.setCheckCodeInDate(roomHouseFilings.getCheckCodeInDate());
            roomHouseFilingsRepository.updateById(filings);
        } else {
            roomHouseFilingsRepository.save(roomHouseFilings);
        }
        // 保存请求/响应备案日志
        RoomHouseFilingsLogs roomHouseFilingsLogs = new RoomHouseFilingsLogs();
        roomHouseFilingsLogs.setRoomHouseId(Long.valueOf(inventoryCheckBo.getUniqueDataId()));
        roomHouseFilingsLogs.setUrl(UriEnum.INVENTORY_CHECK_URI.getUri());
        roomHouseFilingsLogs.setStatus(response.getStatus().toString());
        roomHouseFilingsLogs.setSendJson(JSONObject.toJSONString(inventoryCheckBo));
        roomHouseFilingsLogs.setReceiveJson(JSONObject.toJSONString(response));
        roomHouseFilingsLogs.setErrMsg(response.getMsg());
        roomHouseFilingsLogs.setTenantId(inventoryCheckEvent.getTennerId());
        roomHouseFilingsLogsRepository.save(roomHouseFilingsLogs);

    }

    /**
     * 请求合租核验码
     *
     * @param inventoryCheckEvent
     * @param inventoryCheckBo
     * @param resp
     */
    private void roomCheck(InventoryCheckEvent inventoryCheckEvent, InventoryCheckBo inventoryCheckBo, InventoryCheckResp resp) {
        InventoryRoomCheckBo inventoryRoomCheckBo = inventoryCheckEvent.getInventoryRoomCheckBo();
        inventoryRoomCheckBo.setParentHouseId(resp.getHouseId());
        log.info("备案事件--合租核验码申请,请求数据:{}", JSONObject.toJSONString(inventoryRoomCheckBo));
        CommonFilingsResponse<InventoryRoomCheckResp> roomCheckResp = null;
        try {
            roomCheckResp = inventoryRoomCheckApi.execute(inventoryRoomCheckBo, UriEnum.INVENTORY_ROOM_CHECK_URI, InventoryRoomCheckResp.class);
        } catch (Exception e) {
            roomCheckResp.setStatus(false);
            roomCheckResp.setMsg(e.getMessage());
            log.error("InventoryCheckListener -> roomCheck异常:", e);
        }
        log.info("备案事件--合租核验码申请--响应,ParentRoomHouseId：{},响应:{}", inventoryRoomCheckBo.getUniqueDataId(), JSONObject.toJSONString(roomCheckResp));
        List<RoomHouseFilings> roomHouseFilings = new ArrayList<>();
        if (roomCheckResp.getStatus()) {
            InventoryRoomCheckResp roomCheck = roomCheckResp.getData();
            roomCheck.getRooms().stream().forEach(room -> {
                RoomHouseFilings roomCheckFilings = new RoomHouseFilings();
                roomCheckFilings.setExternalHouseId(room.getRoomId());
                roomCheckFilings.setStatus(RoomHouseFilingsStatus.SUCCESS.getCode());
                roomCheckFilings.setCheckCode(room.getCheckCode());
                roomCheckFilings.setCheckCodeInDate(room.getCheckCodeIndate());
                roomCheckFilings.setTenantId(inventoryCheckEvent.getTennerId());
                roomCheckFilings.setSupperHouseId(Long.valueOf(inventoryCheckBo.getUniqueDataId()));
                // 通过房间名和上级房源查询该房间id
                RoomHouse roomHouse = roomHouseRepository.getByRoomNameIdAndSuperId(room.getRoomName(), roomCheckFilings.getSupperHouseId());
                Assert.isTrue(ObjectUtil.isNotEmpty(roomHouse), "未找到房间信息roomName:{},superRoomId:{}", room.getRoomName(), roomCheckFilings.getSupperHouseId());
                roomCheckFilings.setRoomHouseId(roomHouse.getId());
                roomHouseFilings.add(roomCheckFilings);

                // 推送核验码到es
                // 更新ES数据
                List<RoomelUpdateReqVO> roomelUpdateReqVOS = new ArrayList<>();
                RoomelUpdateReqVO roomelUpdateReqVO = new RoomelUpdateReqVO();
                roomelUpdateReqVO.setId(roomHouse.getId());
                roomelUpdateReqVO.setCheckCode(room.getCheckCode());
                roomelUpdateReqVO.setCheckCodeInDate(room.getCheckCodeIndate());
                roomelUpdateReqVOS.add(roomelUpdateReqVO);
                // 更新房源信息到es
                roomEsProducer.updateBatchRoomEl(roomelUpdateReqVOS);

            });
        } else {
            List<InventoryRoomCheckBo.HouseRoom> leaseSubHouseSets = inventoryRoomCheckBo.getLeaseSubHouseSets();
            for (InventoryRoomCheckBo.HouseRoom leaseSubHouseSet : leaseSubHouseSets) {
                RoomHouseFilings checkFilings = new RoomHouseFilings();
                checkFilings.setStatus(RoomHouseFilingsStatus.ERROR.getCode());
                checkFilings.setTenantId(inventoryCheckEvent.getTennerId());
                checkFilings.setSupperHouseId(Long.valueOf(inventoryCheckBo.getUniqueDataId()));
                // 通过房间名和上级房源查询该房间id
                RoomHouse roomHouse = roomHouseRepository.getByRoomNameIdAndSuperId(leaseSubHouseSet.getRoomName(), Long.valueOf(inventoryCheckBo.getUniqueDataId()));
                Assert.isTrue(ObjectUtil.isNotEmpty(roomHouse), "未找到房间信息roomName:{},superRoomId:{}", leaseSubHouseSet.getRoomName(), inventoryCheckBo.getUniqueDataId());
                checkFilings.setRoomHouseId(roomHouse.getId());
                roomHouseFilings.add(checkFilings);
            }
        }

        // 保存备案响应数据
        for (RoomHouseFilings roomHouseFiling : roomHouseFilings) {
            // 如果之前有备案过,则更新原纪录
            RoomHouseFilings filings = roomHouseFilingsRepository.getByRoomHouseId(roomHouseFiling.getRoomHouseId());
            if (ObjectUtil.isNotEmpty(filings)) {
                filings.setExternalHouseId(roomHouseFiling.getExternalHouseId());
                filings.setStatus(roomHouseFiling.getStatus());
                filings.setCheckCode(roomHouseFiling.getCheckCode());
                filings.setCheckCodeInDate(roomHouseFiling.getCheckCodeInDate());
                roomHouseFilingsRepository.updateById(filings);
            } else {
                roomHouseFilingsRepository.save(roomHouseFiling);
            }

            // 保存请求/响应备案日志
            RoomHouseFilingsLogs roomHouseFilingsLogs = new RoomHouseFilingsLogs();
            roomHouseFilingsLogs.setRoomHouseId(roomHouseFiling.getRoomHouseId());
            roomHouseFilingsLogs.setUrl(UriEnum.INVENTORY_CHECK_URI.getUri());
            roomHouseFilingsLogs.setStatus(roomCheckResp.getStatus().toString());
            roomHouseFilingsLogs.setSendJson(JSONObject.toJSONString(inventoryRoomCheckBo));
            roomHouseFilingsLogs.setReceiveJson(JSONObject.toJSONString(roomCheckResp));
            roomHouseFilingsLogs.setErrMsg(roomCheckResp.getMsg());
            roomHouseFilingsLogs.setTenantId(inventoryCheckEvent.getTennerId());
            roomHouseFilingsLogsRepository.save(roomHouseFilingsLogs);
        }
    }
}
